/* -*- mode: c -*-
 * Copyright (C) 2010, 2011 Lluís Vilanova <vilanova@ac.upc.edu>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef TF_XM_H
#define TF_XM_H

#ifdef __cplusplus
extern "C" {
#endif

/** @file Teraflux execution management primitives. */

#include <stdint.h>


extern uint16_t tf_xm_failed_core;
extern uint16_t tf_xm_failed_node;
extern uint16_t tf_xm_failed_host;

/** Start running all cores.
 *
 * Starts @ref tf_xm_get_cores processes for the current application.
 *
 * When called by the master process (see @ref TF_XM_MASTER), @ref
 * tf_xm_get_cores slave processes are started, whose standard and error outputs
 * are redirected to the master process.
 *
 * The slave processes will be executed as any other program; that is, they will
 * start at the user's @e main routine, and will block on the call to @ref
 * tf_xm_start until all of them reach that point (thus acting as a barrier).
 *
 * The application's master process will block on the call to @ref tf_xm_start
 * until all slave processes finish successfully, or until any of them aborts
 * its execution (see @ref tf_xm_failed_core, @ref tf_xm_failed_node and @ref
 * tf_xm_failed_host).
 *
 * While blocked, the master process will get any stdout/stderr messages from
 * the slave processes, and print it to its stdout (thus the user will be able
 * to see the outputs of all slaves in a single place).
 *
 * @warning If a slave or master process creates another process through @ref
 *          fork or @ref pthread_create (or any other process-creating routine),
 *          the child will have the same ID as the parent (@ref tf_xm_whoami),
 *          as well as it will run on the same physical core.
 *
 * @pre No TF-specific operation or transaction is in flight (e.g., no acquired
 *      memory).
 *
 * @param argc Value of @e argc passed to the slaves' @e main routine.
 * @param argv Value of @e argv passed to the slaves' @e main routine.
 * @return Zero on success. On error, returns the error code of a child (if it
 *         has exited, identified by tf_xm_failed_* variables), and sets errno
 *         appropiately.
 */
int tf_xm_start (int argc, char * argv[]);

/** Get the number of cores.
 *
 * Returns the value of a previous call to @ref tf_xm_set_cores.
 *
 * If the number of cores was not set, returns the value of the environment
 * variable @e TF_XM_CORES .
 *
 * Otherwise, returns the total number of cores available on the system.
 */
uint16_t tf_xm_get_cores (void);

/** Set the number of cores.
 *
 * When set to zero, uses the maximum number of available cores on the system.
 *
 * @pre Called before @ref tf_xm_start, otherwise the result is undefined.
 */
void tf_xm_set_cores (const uint16_t ncores);


/** The @ref tf_xm_whoami value for the master process.
 *
 * The master process will stop executing code once @ref tf_xm_start is called,
 * at which point the master process will serve only the purpose of writing
 * messages from other processes to the terminal.
 */
#define TF_XM_MASTER (((uint16_t)~((uint16_t)0)) - 1)

/** The global ID of core/process assigned to the caller. */
uint16_t dfrt_whoami (void);

#ifdef __cplusplus
}
#endif

#endif  /* TF_XM_H */
